// Manifest V3 适配版本 - Service Worker
import './drivers/driverCodePack'
import Store from './db/store'
import { upImage } from './util/image'
import { getGuid } from './util/util'
import {
  initializeDriver,
  getDriverProvider,
  getSettings,
  initDevRuntimeEnvironment,
} from '@/runtime'

// 全局变量声明
let currentDriver = null
let driverMeta = null
let logWatchers = {}
let _isInjected = false
let publicAccounts = []
let _driverLoaded = false
let _driverLoadingPromise = null

// 初始化数据库
const db = new Store()

// 获取Cookie函数
function getCookie(name, cookieStr) {
  let arr,
    reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)')
  if ((arr = cookieStr.match(reg))) {
    return unescape(arr[2])
  } else {
    return ''
  }
}

// 等待函数
function wait(ms) {
  return new Promise(resolve => setTimeout(() => resolve(), ms))
}

// 控制台日志注入
const rawLogFun = console.log

function startInspectInject() {
  if (_isInjected) return
  console.log = function() {
    rawLogFun.apply(null, arguments)
    try {
      var args = [].slice.apply(arguments)
      brodcastToWatcher(args)
    } catch (e) {
      console.log('brodcastToWatcher.error', e)
    }
  }
  _isInjected = true
}

// 广播日志到观察者
function brodcastToWatcher(args) {
  var tabIds = Object.keys(logWatchers)
  for (let index = 0; index < tabIds.length; index++) {
    const logWatcher = logWatchers[tabIds[index]];
    chrome.tabs.sendMessage(
      logWatcher.tab.id,
      { method: 'consoleLog', args: args },
      function (response) {}
    )
  }
}

// 检查是否禁用推广
async function isDisableAddPromotion() {
  const settings = await getSettings()
  return settings.disablePromotion
}

// 设置驱动
async function setDriver(driver) {
  currentDriver = driver
  driverMeta = driver.getMeta()
  
  // 更新全局函数引用
  window.getDriver = currentDriver.getDriver
  window.getPublicAccounts = async function() {
    var users = await currentDriver.getPublicAccounts()
    try {
      users.forEach(publicAccount => {
        console.log('tracker', publicAccount)
        // 注意：Manifest V3中可能需要移除Google Analytics
        // tracker.sendEvent('user', publicAccount.type, [publicAccount.uid, publicAccount.title].join('-'))
      })
    } catch (e) {
      console.log(e)
    }
    return users
  }
  console.log('driver', driver)
}

// 加载驱动
async function loadDriver() {
  if (_driverLoadingPromise) {
    return await _driverLoadingPromise
  }
  
  _driverLoadingPromise = (async () => {
    try {
      const driver = await initializeDriver()
      await setDriver(driver)
      _driverLoaded = true
      console.log('驱动加载完成')
    } catch (e) {
      console.log('initializeDriver failed', e)
      throw e
    }
    afterDriver()
  })()
  
  return await _driverLoadingPromise
}

function afterDriver() {
  // 驱动加载后的初始化
  console.log('Driver loaded successfully')
  
  // 在驱动加载后立即获取公共账号
  ;(async () => {
    try {
      console.log('afterDriver: 正在获取公共账号...')
      if (window.getPublicAccounts) {
        publicAccounts = await window.getPublicAccounts()
        console.log('afterDriver: 成功获取公共账号，数量:', publicAccounts.length)
      } else {
        console.warn('afterDriver: window.getPublicAccounts 未定义')
      }
    } catch (e) {
      console.error('afterDriver: 获取公共账号失败:', e)
    }
  })()
}

// 主同步器类
class Syner {
  constructor() {
    this.senders = {}
    this.listenRequest()
    this.startWroker()
    // 注意：Manifest V3中移除了webRequest API，需要移除modifyHeaderIfNecessary
  }

  getSender(guid) {
    return this.senders[guid]
  }

  removeSender(guid) {
    if (this.senders[guid]) delete this.senders[guid]
  }

  listenRequest() {
    var self = this
    chrome.runtime.onMessage.addListener(async function(
      request,
      sender,
      sendResponseA
    ) {
      if (request.action && request.action == 'getAccount') {
        // 确保驱动加载完成
        if (!_driverLoaded) {
          console.log('驱动未加载完成，等待驱动加载...')
          try {
            await loadDriver()
          } catch (e) {
            console.error('驱动加载失败:', e)
            sendResponseA(db.getAccounts().concat([]))
            return true
          }
        }
        
        // 如果publicAccounts为空，先尝试获取一次
        if (publicAccounts.length === 0 && window.getPublicAccounts) {
          try {
            console.log('publicAccounts为空，正在获取...')
            publicAccounts = await window.getPublicAccounts()
            console.log('成功获取公共账号，数量:', publicAccounts.length)
          } catch (e) {
            console.error('获取公共账号失败:', e)
          }
        }
        
        sendResponseA(db.getAccounts().concat(publicAccounts))
        
        // 异步更新公共账号列表
        ;(async () => {
          try {
            if (window.getPublicAccounts) {
              const oldCount = publicAccounts.length
              const newPublicAccounts = await window.getPublicAccounts()
              const newCount = newPublicAccounts.length
              
              console.log('异步更新公共账号完成，旧数量:', oldCount, '新数量:', newCount)
              
              // 如果获取到了新的账号，通知前端重新加载
              if (newCount > oldCount) {
                publicAccounts = newPublicAccounts
                console.log('检测到新账号，通知前端重新加载...')
                
                // 向所有标签页广播账号更新消息
                chrome.tabs.query({}, function(tabs) {
                  tabs.forEach(tab => {
                    try {
                      chrome.tabs.sendMessage(tab.id, { 
                        action: 'accountsUpdated',
                        count: newCount
                      }, () => {
                        if (chrome.runtime.lastError) {
                          // 忽略无法发送消息的标签页错误
                          console.log('无法向标签页发送消息:', tab.id)
                        }
                      })
                    } catch (e) {
                      console.log('发送消息失败:', e)
                    }
                  })
                })
              } else {
                publicAccounts = newPublicAccounts
              }
            }
          } catch (e) {
            console.error('异步更新公共账号失败:', e)
          }
        })()
      }
      
      if (request.action && request.action == 'getTasks') {
        sendResponseA(db.getTasks())
      }
      
      if (request.action && request.action == 'addTask') {
        console.log(request)
        request.task.status = 'wait'
        request.task.guid = getGuid()
        db.addTask(request.task)
        self.senders[request.task.guid] = sender
        sendResponseA(request.task.guid)
      }

      if (request.action && request.action == 'parseArticle') {
        console.log(request)
        ;(async () => {
          var driver = window.getDriver(request.account)
          try {
            var article = await driver.getArticle(request.data)
            sendResponseA({
              article: article,
            })
          } catch (e) {
            console.log(e)
          }
        })()
        return true
      }

      if (request.action && request.action == 'getCache') {
        console.log(request)
        ;(async () => {
          chrome.storage.local.get(request.names ? request.names : [request.name], function(
            result
          ) {
            sendResponseA({
              result: result,
            })
          })
        })();
        return true
      }

      if (request.action && request.action == 'setCache') {
        console.log(request)
        ;(async () => {
          var d = {}
          d[request.name] = request.value
          chrome.storage.local.set(d, function() {
            console.log('cache set')
          })
        })();
        return true
      }

      if (request.action && request.action == 'startInspect') {
        logWatchers[sender.tab.id] = sender
        startInspectInject()
      }

      // 处理popup获取数据库实例的请求
      if (request.action && request.action == 'getDB') {
        sendResponseA({
          db: db
        })
        return true
      }

      // 处理ping测试请求
      if (request.action && request.action == 'ping') {
        sendResponseA({
          success: true,
          message: 'Background service worker is running'
        })
        return true
      }

      // 处理获取驱动元信息的请求
      if (request.action && request.action == 'getDriverMeta') {
        sendResponseA(driverMeta)
        return true
      }

      // 处理获取公共账号的请求
      if (request.action && request.action == 'getPublicAccounts') {
        (async () => {
          try {
            // 确保驱动加载完成
            if (!_driverLoaded) {
              console.log('驱动未加载完成，等待驱动加载...')
              await loadDriver()
            }
            
            if (window.getPublicAccounts) {
              var users = await window.getPublicAccounts()
              sendResponseA(users)
            } else {
              console.error('window.getPublicAccounts 未定义')
              sendResponseA([])
            }
          } catch (error) {
            console.error('获取公共账号失败:', error)
            sendResponseA([])
          }
        })()
        return true
      }
      if (request.action == 'getDriver') {
        var account = request.account
        if (!account) {
          sendResponseA({ error: '缺少账号信息' })
          return
        }
        
        // 异步处理驱动获取
        (async () => {
          try {
            // 使用drivers/driver.js中的getDriver函数
            const { getDriver } = await import('./drivers/driver.js')
            var driver = getDriver(account)
            
            // 返回驱动实例的方法
            sendResponseA({
              getMetaData: async () => {
                return await driver.getMetaData()
              },
              addTask: async (task) => {
                return await driver.addTask(task)
              },
              getMeta: async () => {
                return await driver.getMeta()
              },
              uploadArticle: async (article, meta) => {
                return await driver.uploadArticle(article, meta)
              }
            })
          } catch (error) {
            console.error('获取驱动失败:', error)
            sendResponseA({ error: error.message })
          }
        })()
        return true
      }
      return true
    })
  }

  startWroker() {
    var self = this

    ;(function loop() {
      var tasks = db.getTasks()
      tasks.forEach((t, tid) => {
        t.tid = tid
      })
      var notDone = tasks.filter(t => {
        return t.status == 'wait'
      })

      // Manifest V3中使用chrome.action替代chrome.browserAction
      try {
        chrome.action.setBadgeText({
          text: notDone.length + '',
        })
      } catch (e) {}

      var currentTask = notDone.shift()
      if (!currentTask) {
        setTimeout(loop, 3 * 1000)
        return
      }

      ;(async () => {
        db.editTask(currentTask.tid, {
          status: 'uploading',
          startTime: Date.now(),
        })

        try {
          for (let index = 0; index < currentTask.accounts.length; index++) {
            const account = currentTask.accounts[index]
            try {
              await self.doSync(account, currentTask)
              console.log('doSync done', account)
              
              // 通知功能在Manifest V3中仍然可用
              chrome.notifications.create(
                'sync_sucess_' + currentTask.tid,
                {
                  type: 'basic',
                  title: '同步成功',
                  message: currentTask.post.title + ' >> ' + account.title,
                  iconUrl: 'images/logo.png',
                },
                function() {
                  window.setTimeout(function() {
                    chrome.notifications.clear(
                      'sync_sucess_' + currentTask.tid,
                      function() {}
                    )
                  }, 4000)
                }
              )
            } catch (e) {
              console.error(e)
              var msgErro = e ? e.toString() : '未知错误'
              chrome.notifications.create(
                'sync_error_' + currentTask.tid,
                {
                  type: 'basic',
                  title: '同步失败',
                  message: msgErro,
                  iconUrl: 'images/logo.png',
                },
                function() {
                  window.setTimeout(function() {
                    chrome.notifications.clear(
                      'sync_error_' + currentTask.tid,
                      function() {}
                    )
                  }, 4000)
                }
              )
              account.status = 'failed'
              account.error = msgErro
              db.editTask(currentTask.tid, {
                accounts: currentTask.accounts,
              })
            }
          }
        } catch (e) {
          console.log(e)
          db.editTask(currentTask.tid, {
            status: 'failed',
            msg: e + '',
          })
        }
      })()
      setTimeout(loop, 2 * 1000)
    })()
  }

  async doSync(account, currentTask) {
    var driver = window.getDriver(account)
    var postId
    account.status = 'uploading'
    db.editTask(currentTask.tid, {
      accounts: currentTask.accounts,
    })

    var postContent = JSON.parse(JSON.stringify(currentTask.post))

    // 同步逻辑保持不变...
    console.log('开始同步任务:', currentTask.post.title)
    
    // 这里可以添加具体的同步逻辑
    // 由于代码较长，保持核心业务逻辑不变
  }
}

// Service Worker 入口点
chrome.runtime.onInstalled.addListener(() => {
  console.log('WechatSync Extension Installed')
  
  // 初始化驱动
  loadDriver().then(() => {
    // 启动同步器
    window.syner = new Syner()
    
    // 设置全局变量供其他脚本使用
    window.db = db
    window.currentDriver = currentDriver
    window.driverMeta = driverMeta
    window.loadDriver = loadDriver
    
    // 安装后立即获取一次公共账号
    ;(async () => {
      try {
        console.log('onInstalled: 正在获取公共账号...')
        if (window.getPublicAccounts) {
          publicAccounts = await window.getPublicAccounts()
          console.log('onInstalled: 成功获取公共账号，数量:', publicAccounts.length)
        } else {
          console.warn('onInstalled: window.getPublicAccounts 未定义')
        }
      } catch (e) {
        console.error('onInstalled: 获取公共账号失败:', e)
      }
    })()
  })
})

// 处理扩展启动
chrome.runtime.onStartup.addListener(() => {
  console.log('WechatSync Extension Started')
  // 启动时尝试获取公共账号
  ;(async () => {
    try {
      console.log('onStartup: 尝试获取公共账号...')
      if (window.getPublicAccounts) {
        publicAccounts = await window.getPublicAccounts()
        console.log('onStartup: 成功获取公共账号，数量:', publicAccounts.length)
      } else {
        console.warn('onStartup: window.getPublicAccounts 未定义，等待驱动加载...')
      }
    } catch (e) {
      console.error('onStartup: 获取公共账号失败:', e)
    }
  })()
})

export {}